package AIbyDavid;
import java.util.Random;


public class GeneticCode implements Comparable{
	public String code;
	public Random rand;
	long codeFitness;
	public GeneticCode(){
		rand=new Random();
		code=generateCode();
		evaluateCode();
		
	}
	public GeneticCode(String code){
		rand=new Random();
		this.code=code;
		evaluateCode();
		
	}
	public String getCodePart(int from){
		return code.substring(from*11);
	}

	private String generateCode() {
		StringBuilder sb=new StringBuilder(); 
		for(int i=0;i<10;i++){
			sb.append(getVariable());
		}
		return sb.toString();
	}

	private String getVariable() {
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<11;i++){// 11 bin needed to represent +-512
		
			sb.append(rand.nextInt(2));
		}
		return sb.toString();
	}
	public String toString(){
		StringBuilder sb=new StringBuilder();
		StringBuilder sb2=new StringBuilder();
		for(int i=0;i<10;i++){
			sb.append(code.substring(10*i,10*i+10));
			sb.append(";");
			sb2.append(evaluate(code.substring(10*i,10*i+10)));
			sb2.append(";");
		}
		return ""+codeFitness;
		//return sb.toString()+"\n"+sb2.toString()+ "\n Evaluated with the fitness function gives the value: "+codeFitness;
	}
	public void evaluateCode(){// evaluates the whole code using the function given in th assignment
		int sum=0;
		for(int i=0;i<10;i++){
			sum+=Math.pow(evaluate(code.substring(11*i,11*i+11)), 2);// takes the variable to the power of 2 and adds to sum
		}
		codeFitness= -sum;
	}
	public int evaluate(String binary){// binary schould start with a 0 if negative and 1 if positive
		if(Integer.parseInt(binary.substring(0, 1))==1){
			return Integer.parseInt(binary.substring(1), 2);
		}else{
			return -Integer.parseInt(binary.substring(1), 2);
		}
		
	}

	public GeneticCode merge(GeneticCode geneticCode) {
		int breakPoint=rand.nextInt(9)+1; //rand 1-9
		return new GeneticCode(code.substring(0, breakPoint*11)+geneticCode.getCodePart(breakPoint));
	}
	public void mutate() {
		int numberOfMutations=rand.nextInt(2)+1; //rand 1-2
		for(int i=0;i<numberOfMutations;i++){
			int gene=rand.nextInt(109)+1;
			//int gene=rand.nextInt(10)*11; //Endast minst signifikanta siffran
			code=code.substring(0,gene)+rand.nextInt(2)+code.substring(gene+1);
		}
		// TODO Auto-generated method stub
		
	}
	@Override
	public int compareTo(Object arg0) {
		if(arg0 instanceof GeneticCode){
			long val=((GeneticCode) arg0).codeFitness;
			return (int) (val-codeFitness);
		}
		return 0;
	}
}
